/* iecompat.js
*
* Copyright Ma Bingyao <andot@ujn.edu.cn>
* Version: 1.3
* LastModified: 2006-08-29
* @2006-08-29 fix decodeURI method bugs with checkutf8
* This library is free.  You can redistribute it and/or modify it.
* http://www.coolcode.cn/?p=126
* Format: 1 tab indent(4 spaces), LF, ASCII, no-BOM
* rebuild by DSON <dsonet@msn.com>
* @version $Id: iecompat.js 104 2010-01-07 12:03:16Z dsonet@gmail.com $
*/

/*@cc_on @*/

/*@if (@_jscript_version < 5.5)

(function(context){

@if (@_jscript_version < 5)

context.Error = function Error(num, msg) {
	this.number = (typeof num === "number") ? num : 0;
	this.message = this.description = msg || "";
}
@end

context.undefined = context.undefined;

function extend(cls, prop)
{
	var p = cls.prototype, o, pn;
	for(o in prop)
	{
		if(!p[o])
		{
			pn = prop[o];
			p[o] = typeof pn === "function" ? pn : typeof pn === "string" ? p[pn] : p[o];
		}
	}
}
extend(Object, {
	// this return value is not very correct
	isPrototypeOf: function (o) {
		return (this.constructor === o.constructor);
	},
	// this return value is not very correct
	hasOwnProperty: function (pName) {
		return (typeof(eval("this." + pName)) !== "undefined");
	},
	propertyIsEnumerable: function (pName) {
		for (var o in this) {
			if ((pName === o.toString()) && 
				(pName !== "propertyIsEnumerable") && 
				(pName !== "isPrototypeOf") && 
				(pName !== "hasOwnProperty")) return true;
		}
		return false;
	}
});
extend(Error, {
	message: "",
	name: "Error"
});
extend(Date, {
	toDateString: function () {
		var s = this.toString().split(" ");
		return [s[0], s[1], s[2], s[5]].join(" ");
	},
	toTimeString: function () {
		var s = this.toString().split(" ");
		return [s[3], s[4]].join(" ");
	},
	toLocaleDateString: function () {
		return this.toLocaleString().split(" ")[0];
	},
	toLocaleTimeString: function () {
		return this.toLocaleString().split(" ")[1];
	}
});
extend(Number, {
	toExponential: function (n) {
		if (!n) {
			n = 0;
		}
		else {
			n = parseInt(n);
			if (n < 0 || n > 20) {
					@if (@_jscript_version < 5)
						return null;
					@else
						var e = new Error(-2146823262, "The number of fractional digits is out of range");
						e.name = "RangeError";
						throw e;
					@end
			}
		}
		var s, d, e, len;
		s = this.toString().split("e");
		d = parseFloat(s[0]);
		e = 0;
		if (typeof s[1] !== "undefined") {
			e = parseInt(s[1]);
		}
		s = d.toString().split(".");
		if (typeof s[1] !== "undefined") {
			e = e - s[1].length;
			d = s[0] + s[1];
			d = d.replace(/^0+/g, "");
			if (d === "") d = "0";
		}
		s = d.toString();
		len = s.length - 1;
		e += len;
		if (len < n) {
			s += repeat("0", n - len);
		}
		else if (len > n) {
			s = Math.round(parseFloat("." + s) * Math.pow(10, n + 1)).toString();
			if ((s.length - 1) > n) {
					e += 1;
					s = Math.round(parseFloat("." + s) * Math.pow(10, n + 1)).toString();
			}
		}
		if (e >= 0) {
			e = "+" + e;
		}
		if (n === 0) {
			return s + "e" + e;
		}
		else {
			return s.substr(0, 1) + "." + s.substr(1) + "e" + e;
		}
	},
	toFixed: function (n) {
		if (!n) {
			n = 0;
		}
		else {
			n = parseInt(n);
			if (n < 0 || n > 20) {
					@if (@_jscript_version < 5)
						return null;
					@else
						var e = new Error(-2146823262, "The number of fractional digits is out of range");
						e.name = "RangeError";
						throw e;
					@end
			}
		}
		var s, d, e, len;
		s = this.toString().split("e");
		d = parseFloat(s[0]);
		e = 0;
		if (typeof s[1] !== "undefined") {
			e = parseInt(s[1]);
		}
		s = d.toString().split(".");
		if (typeof s[1] !== "undefined") {
			e = e - s[1].length;
			d = s[0] + s[1];
			d = d.replace(/^0+/g, "");
			if (d === "") d = "0";
		}
		s = d.toString();
		len = s.length - 1;
		
		if (e >= 0) {
			s += repeat("0", e);
			if (n > 0) {
					s += "." + repeat("0", n);
			}
		}
		else if (-e <= n) {
			s = repeat("0", 1 - e - s.length) + s;
			s = s.substr(0, s.length + e) + "." + s.substr(s.length + e) + repeat("0", n + e);
		}
		else {
			s = repeat("0", 1 - e - s.length) + s;
			d = parseFloat(s.substr(0, s.length + e) + "." + s.substr(s.length + e));
			s = Math.round(d * Math.pow(10, n)).toString();
			if (n > 0) {
					s = repeat("0", n - s.length + 1) + s;
					s = s.substr(0, s.length - n) + "." + s.substr(s.length - n);
			}
		}
		return s;
	},
	toPrecision: function (n) {
		if (typeof n === "undefined") {
			return this.toString();
		}
		else {
			n = parseInt(n);
			if (n < 1 || n > 21) {
					@if (@_jscript_version < 5)
						return null;
					@else
						var e = new Error(-2146823262, "The precision is out of range");
						e.name = "RangeError";
						throw e;
					@end
			}
		}
		if (this.valueOf() === 0) {
			if (n === 1) return "0";
			return "0." + repeat("0", n - 1);
		}
		var s, d, e, len;
		s = this.toString().split("e");
		d = parseFloat(s[0]);
		e = 0;
		if (typeof s[1] !== "undefined") {
			e = parseInt(s[1]);
		}
		s = d.toString().split(".");
		if (typeof s[1] !== "undefined") {
			e = e - s[1].length;
			d = s[0] + s[1];
			d = d.replace(/^0+/g, "");
			if (d === "") d = "0";
		}
		s = d.toString();
		len = s.length;
		d = parseFloat("." + s) * Math.pow(10, n);
		s = Math.round(d).toString();
		if (s.length > parseInt(d).toString().length) {
			e++;
			s = s.slice(0, -1);
		}
		e += len - s.length;
		len = s.length;
		e += len - 1;

		if (e < n && e > -7) {
			if ((e < n - 1) && (e > 0)) {
					s = s.substr(0, e + 1) + "." + s.substr(e + 1);
			}
			else if (e <= 0) {
					s = repeat("0", - e) + s;
					s = s.substr(0, 1) + "." + s.substr(1);
			}
		}
		else {
			if (len < n) {
					s += repeat("0", n - len);
			}
			if (e >= 0) {
					e = "+" + e;
			}
			if (n === 1) {
					s += "e" + e;
			}
			else {
					s = s.substr(0, 1) + "." + s.substr(1) + "e" + e;
			}
		}
		return s;
	}
});
extend(String, {
	charCodeAt: function(index){
		var c = escape(this.charAt(index));
		if(c.length >3){
			c = c.substr(2);
		}else{
			c = c.substr(1);
		}
		return parseInt(c, 16);
	},
	localeCompare: function (str) {
		if (this > str) return 1;
		if (this < str) return -1;
		return 0;
	},
	toLocaleLowerCase: "toLowerCase",
	toLocaleUpperCase: "toUpperCase"
});

if ("".replace(/^/,String))
{
	//preserve String.replace
	var $replace = String.prototype.replace;

	extend(String, {
		replace: function (r, m)
		{
			if (typeof m === "function")
			{
				if (typeof r === "string")
				{
					return $replace.call(this, r, m(r));
				}
				else if (r && r.constructor === RegExp)
				{
					var mc,
						s1 = this,
						s2 = "",
						r2 = new RegExp(r.source, r.ignoreCase ? "i" : "");
					while (s1 && (mc = r2.exec(s1)))
					{
						s2 += s1.slice(0, mc.index) + m.apply(null, mc);

						s1 = s1.slice(mc.index + mc[0].length);

						if (!r.global) break;
					}
					return s2 + s1;
				}
				else
				{
					return $replace.call(this, String(r), m);
				}
			}
			else
			{
				return $replace.call(this, r, m);
			}
		}
	});
}
extend(Array, {
	push: function () {
		var curlen = this.length,
			agrsLen = arguments.length,
			i;
		for (i = 0; i < agrsLen; i++) {
			this[curlen + i] = arguments[i];
		}
		return this.length;
	},
	pop: function () {
		var rtv = this[this.length - 1];
		--this.length;
	},
	shift: function () {
		var rtv = this[0],
			i;
		for (i = 1; i < this.length; i++) {
			this[i - 1] = this[i];
		}
		--this.length;
		return rtv;
	},
	unshift: function () {
		var curlen = this.length,
			arglen = arguments.length,
			i;
		for (i = curlen - 1; i >= 0 ; --i) {
			this[i + arglen] = this[i] ;
		}
		for (i = 0; i < arglen; ++i) {
			this[i] = arguments[i];
		}
		//return this.length;  // return this value is Gecko/Opera implementation. but IE don't return anything.
	},
	splice: function () {
		var start = arguments[0],
			deleteCount = Math.max(arguments[1],0),
			len = Math.min(arguments.length - 2,0),
			rtv = this.slice(start),
			i;
		for (i = 0; i < len; i++) {
			this[start + i] = arguments[i + 2];
		}
		for (i = 0; i < rtv.length - deleteCount; i++) {
			this[start + len + i] = rtv[deleteCount + i];
		}
		this.length = start + len + rtv.length - deleteCount;
		rtv.length = deleteCount;
		return rtv;
	}
});
extend(Function, {
	apply: function (o, p) {
		var ps = "";
		if (typeof o === "undefined") {
			return this();
		}
		if (p) {
			if (typeof p[0] === "undefined" && typeof p.length !== "number") {
					@if (@_jscript_version < 5)
						return null;
					@else
						var e = new Error(-2146823260, "Array or arguments object expected");
						e.name = "TypeError";
						throw e;
					@end
			}
			ps = "p[0]";
			for (var i = 1; i < p.length; i++) {
				ps += ", p["+i+"]";
			}
		}
		if (o === null || o === context) {
			return eval("this("+ ps +");");
		}
		if (typeof o === "object" || typeof o === "function") {
			var ns = "__10b7bdb5dd95e4f2708cfa36f3569503";
			try{
				o[ns] = this;
				return eval("o[ns](" + ps + ");");
			}finally{
				delete o[ns];
			}
		}
		else {
			return eval("this(" + ps + ");");
		}
	},
	call: function (o) {
		return this.apply(Array.prototype.shift.apply(arguments), arguments);
	}
});
var uriChars = ["%00", "%01", "%02", "%03", "%04", "%05", "%06",
	"%07", "%08", "%09", "%0A", "%0B", "%0C", "%0D",
	"%0E", "%0F", "%10", "%11", "%12", "%13", "%14",
	"%15", "%16", "%17", "%18", "%19", "%1A", "%1B",
	"%1C", "%1D", "%1E", "%1F", "%20", "!", "%22",
	"#", "$", "%25", "&", "\"", "(", ")", "*", "+", ",",
	"-", ".", "/", "0", "1", "2", "3", "4", "5", "6",
	"7", "8", "9", ":", ";", "%3C", "=", "%3E", "?",
	"@", "A", "B", "C", "D", "E", "F", "G", "H", "I",
	"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
	"T", "U", "V", "W", "X", "Y", "Z", "%5B", "%5C",
	"%5D", "%5E", "_", "%60", "a", "b", "c", "d", "e",
	"f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
	"p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
	"z", "%7B", "%7C", "%7D", "~", "%7F"];
context.encodeURI = function encodeURI(str) {
	var out = [], i, j, len = str.length, c, c2;

	for (i = 0, j = 0; i < len; i++) {
		c = str.charCodeAt(i);
		if (c <= 0x007F) {
				out[j++] = uriChars[c];
				continue;
		}
		else if (c <= 0x7FF) {
				out[j++] = "%" + (0xC0 | ((c >>  6) & 0x1F)).toString(16).toUpperCase();
				out[j++] = "%" + (0x80 | (		c & 0x3F)).toString(16).toUpperCase();
				continue;
		}
		else if (c < 0xD800 || c > 0xDFFF) {
				out[j++] = "%" + (0xE0 | ((c >> 12) & 0x0F)).toString(16).toUpperCase();
				out[j++] = "%" + (0x80 | ((c >>  6) & 0x3F)).toString(16).toUpperCase();
				out[j++] = "%" + (0x80 |			(c & 0x3F)).toString(16).toUpperCase();
				continue;
		}
		else {
				if (++i < len) {
					c2 = str.charCodeAt(i);
					if (c <= 0xDBFF && 0xDC00 <= c2 && c2 <= 0xDFFF) {
						c = ((c & 0x03FF) << 10 | (c2 & 0x03FF)) + 0x010000;
						if (0x010000 <= c && c <= 0x10FFFF) {
								out[j++] = "%" + (0xF0 | ((c >>> 18) & 0x3F)).toString(16).toUpperCase();
								out[j++] = "%" + (0x80 | ((c >>> 12) & 0x3F)).toString(16).toUpperCase();
								out[j++] = "%" + (0x80 | ((c >>>  6) & 0x3F)).toString(16).toUpperCase();
								out[j++] = "%" + (0x80 |			(c & 0x3F)).toString(16).toUpperCase();
								continue;
						}
					}
				}
		}
		return throwUriEncodeErr();
	}
	return out.join("");
}

context.encodeURIComponent = function encodeURIComponent(str) {
	var out = [], i, j, len = str.length, c;

	for(i = 0, j = 0; i < len; i++) {
		c = str.charCodeAt(i);
		if (c <= 0x007F) {
				out[j++] = uriChars[c];
				continue;
		}
		else if (c <= 0x7FF) {
				out[j++] = "%" + (0xC0 | ((c >>  6) & 0x1F)).toString(16).toUpperCase();
				out[j++] = "%" + (0x80 | (		c & 0x3F)).toString(16).toUpperCase();
				continue;
		}
		else if (c < 0xD800 || c > 0xDFFF) {
				out[j++] = "%" + (0xE0 | ((c >> 12) & 0x0F)).toString(16).toUpperCase();
				out[j++] = "%" + (0x80 | ((c >>  6) & 0x3F)).toString(16).toUpperCase();
				out[j++] = "%" + (0x80 |			(c & 0x3F)).toString(16).toUpperCase();
				continue;
		}
		else {
				if (++i < len) {
					c2 = str.charCodeAt(i);
					if (c <= 0xDBFF && 0xDC00 <= c2 && c2 <= 0xDFFF) {
						c = ((c & 0x03FF) << 10 | (c2 & 0x03FF)) + 0x010000;
						if (0x010000 <= c && c <= 0x10FFFF) {
								out[j++] = "%" + (0xF0 | ((c >>> 18) & 0x3F)).toString(16).toUpperCase();
								out[j++] = "%" + (0x80 | ((c >>> 12) & 0x3F)).toString(16).toUpperCase();
								out[j++] = "%" + (0x80 | ((c >>>  6) & 0x3F)).toString(16).toUpperCase();
								out[j++] = "%" + (0x80 |			(c & 0x3F)).toString(16).toUpperCase();
								continue;
						}
					}
				}
		}
		return throwUriEncodeErr();
	}
	return out.join("");
}

context.decodeURIComponent = function decodeURIComponent(str) {
	var out = [], i =0, j = 0, len = str.length;
	var c, c2, c3, c4, s;

	while(i < len) {
		c = str.charCodeAt(i++);
		if (c === 37) {
				if ((c = checkcode(str, i++, i++)) === null) return null;
		}
		else {
				out[j++] = String.fromCharCode(c);
				continue;
		}
		switch(c >> 4) { 
				case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
					// 0xxxxxxx
					out[j++] = String.fromCharCode(c);
					break;
				}
				case 12: case 13: {
					// 110x xxxx	10xx xxxx
					if ((c2 = checkutf8(str, i++, i++, i++)) === null) return null;
					out[j++] = String.fromCharCode(((c & 0x1F) << 6) | (c2 & 0x3F));
					break;
				}
				case 14: {
					// 1110 xxxx  10xx xxxx  10xx xxxx
					if ((c2 = checkutf8(str, i++, i++, i++)) === null) return null;
					if ((c3 = checkutf8(str, i++, i++, i++)) === null) return null;
					out[j++] = String.fromCharCode(((c & 0x0F) << 12) |
						((c2 & 0x3F) << 6) | ((c3 & 0x3F) << 0));
					break;
				}
				default: {
					switch (c & 0xf) {
						case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
								// 1111 0xxx  10xx xxxx  10xx xxxx  10xx xxxx
								if ((c2 = checkutf8(str, i++, i++, i++)) === null) return null;
								if ((c3 = checkutf8(str, i++, i++, i++)) === null) return null;
								if ((c4 = checkutf8(str, i++, i++, i++)) === null) return null;
								s = ((c  & 0x07) << 18) |
									((c2 & 0x3f) << 12) |
									((c3 & 0x3f) <<  6) |
									(c4 & 0x3f) - 0x10000;
								if (0 <= s && s <= 0xfffff) {
									out[j++] = String.fromCharCode(((s >>> 10) & 0x03ff) | 0xd800,
																				(s			& 0x03ff) | 0xdc00);
								}
								else {
									return throwUriDecodeErr();
								}
								break;
						}
						default: {
								return throwUriDecodeErr();
						}
					}
				}
		}
	}
	return out.join("");
}

context.decodeURI = function decodeURI(str) {
	var out = [], i =0, j = 0, len = str.length;
	var c, c2, c3, c4, s;

	while(i < len) {
		c = str.charCodeAt(i++);
		if (c === 37) {
				if ((c = checkcode(str, i++, i++)) === null) return null;
		}
		else {
				out[j++] = String.fromCharCode(c);
				continue;
		}
		switch(c) {
				case 35: case 36: case 38: case 43: case 44: case 47:
				case 58: case 59: case 61: case 63: case 64: {
					if (str.charCodeAt(i - 3) === 37) {
						out[j++] = str.substr(i - 3, 3);
					}
					else {
						out[j++] = str.substr(i - 1, 1);
					}
					break;
				}
				default: {
					switch (c >> 4) { 
						case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
								// 0xxxxxxx
								out[j++] = String.fromCharCode(c);
								break;
						}
						case 12: case 13: {
								// 110x xxxx	10xx xxxx
								if ((c2 = checkutf8(str, i++, i++, i++)) === null) return null;
								out[j++] = String.fromCharCode(((c & 0x1F) << 6) | (c2 & 0x3F));
								break;
						}
						case 14: {
								// 1110 xxxx  10xx xxxx  10xx xxxx
								if ((c2 = checkutf8(str, i++, i++, i++)) === null) return null;
								if ((c3 = checkutf8(str, i++, i++, i++)) === null) return null;
								out[j++] = String.fromCharCode(((c & 0x0F) << 12) |
									((c2 & 0x3F) << 6) | ((c3 & 0x3F) << 0));
								break;
						}
						default: {
								switch (c & 0xf) {
									case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
										// 1111 0xxx  10xx xxxx  10xx xxxx  10xx xxxx
										if ((c2 = checkutf8(str, i++, i++, i++)) === null) return null;
										if ((c3 = checkutf8(str, i++, i++, i++)) === null) return null;
										if ((c4 = checkutf8(str, i++, i++, i++)) === null) return null;
										s = ((c  & 0x07) << 18) |
												((c2 & 0x3f) << 12) |
												((c3 & 0x3f) <<  6) |
												(c4 & 0x3f) - 0x10000;
										if (0 <= s && s <= 0xfffff) {
												out[j++] = String.fromCharCode(((s >>> 10) & 0x03ff) | 0xd800,
																						(s			& 0x03ff) | 0xdc00);
										}
										else {
												return throwUriDecodeErr();
										}
										break;
									}
									default: {
										return throwUriDecodeErr();
									}
								}
						}
					}
				}
		}
	}
	return out.join("");
}
function throwUriEncodeErr() {
	@if (@_jscript_version < 5)
		return null;
	@else
		var e = new Error(-2146823264, "The URI to be encoded contains an invalid character");
		e.name = "URIError";
		throw e;
	@end
}
function throwUriDecodeErr() {
	@if (@_jscript_version < 5)
		return null;
	@else
		var e = new Error(-2146823263, "The URI to be decoded is not a valid encoding");
		e.name = "URIError";
		throw e;
	@end
}

function checkcode(str, i1, i2) {
	var d1 = str.charAt(i1),
		d2 = str.charAt(i2);
	if (isNaN(parseInt(d1, 16)) || isNaN(parseInt(d2, 16))) {
		return throwUriDecodeErr();
	}
	return parseInt(d1 + d2, 16);
}

function checkutf8(str, i1, i2, i3) {
	var c = str.charCodeAt(i1);
	if (c === 37) {
		if ((c = checkcode(str, i2, i3)) === null) return null;
	}
	if ((c >> 6) !== 2) {
		return throwUriDecodeErr();
	}
	return c;
}

function repeat(s, n) {
	var out = "", i;
	for (i = 0; i < n; i++) {
			out += s;
	}
	return out;
}

})(this);

@end @*/